package com.kedacom.ctsp.authority.service.simple;

import com.kedacom.ctsp.authority.entity.Resource;
import com.kedacom.ctsp.authority.service.ResourceService;
import com.kedacom.ctsp.authority.service.simple.strategy.ResourceChangeStrategy;
import com.kedacom.ctsp.authority.service.simple.strategy.ResourceChangeStrategyFactory;
import com.kedacom.ctsp.lang.Validate;
import com.kedacom.ctsp.lang.validate.ValidationException;
import com.kedacom.ctsp.web.service.StatusEnum;
import com.kedacom.ctsp.web.service.simple.AbstractTreeSortService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author sunchenjie
 * @date 2017/11/12
 */
@Service("authorityResourceService")
public class ResourceServiceImpl extends AbstractTreeSortService<Resource, String> implements ResourceService {

    @Autowired
    protected ApplicationContext context;

    @Autowired
    private ResourceChangeStrategyFactory resourceChangeStrategyFactory;

    @Override
    public String insert(Resource entity) {
        if (entity.getStatus() == null) {
            entity.setStatus(StatusEnum.ENABLE.ordinal());
        }
        Validate.isTrue(checkSignUnique(Resource.SIGN, entity.getClientSign(), entity.getSign().trim()), "auth.resource.sign.duplicated");
        return super.insert(entity);
    }


    public boolean checkSignUnique(String name, String clientSign, String value) {
        Validate.notBlank(name, "unique column cannot be blank.");
        Validate.notBlank(value, "unique columne[%s]'s check value cannot be blank.", name);
        long total = createQuery().where(name, value).in(Resource.CLIENT_SIGN, clientSign).total();
        return !(total > 0);
    }

    @Override
    public String patch(String id, Resource entity) {
        Resource oldEntity = get(id);
        Validate.notNull(oldEntity, "auth.resource.notexist");
        // 修改了sign才需要检测
        if (StringUtils.isNotBlank(oldEntity.getSign()) && !oldEntity.getSign().equals(entity.getSign())) {
            Validate.isTrue(checkChildUnique(Resource.SIGN, entity.getClientSign(), entity.getSign().trim()), "auth.resource.sign.duplicated");
        }

        //上级id，和当前id不能相同
        if (entity.getParent() != null && StringUtils.equals(entity.getParent().getId(), id)) {
            throw new ValidationException("auth.resource.id.parent.id.same.error");
        }

        entity.setId(id);
        return super.patch(id, entity);
    }

    /**
     * 检测子节点是否有重复
     *
     * @param name
     * @param parentId
     * @param value
     * @return
     */
    @Override
    public boolean checkChildUnique(String name, String parentId, String value) {

        Validate.notBlank(name, "unique column cannot be blank.");
        Validate.notBlank(value, "unique columne[%s]'s check value cannot be blank.", name);
        long total = createQuery().where(name, value).in(Resource.PARENT_ID, parentId).total();
        return !(total > 0);
    }

    @Override
    public int submit(Resource entity, String commandId, String comment) {
        int id = super.submit(entity, commandId, comment);

        Set<String> ids = new HashSet<>();
        ids.add(entity.getId());
        ResourceChangeStrategy resourceChangeStrategy = resourceChangeStrategyFactory.getChangeStrategy(commandId);
        resourceChangeStrategy.onChangeEvent(ids);
        return id;
    }

    @Override
    public int submit(Collection<Resource> datas, String commandId, String comment) {
        int id = super.submit(datas, commandId, comment);
        Set<String> ids = datas.stream().map(Resource::getId).collect(Collectors.toSet());
        ResourceChangeStrategy resourceChangeStrategy = resourceChangeStrategyFactory.getChangeStrategy(commandId);
        resourceChangeStrategy.onChangeEvent(ids);
        return id;
    }

}

